package com.uyun.util;

import com.uyun.rbac.permission.entity.MenuEntity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.*;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class AppUtils {

	private final static Log log = LogFactory.getLog(AppUtils.class);

	public final static SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public final static SimpleDateFormat sf_time = new SimpleDateFormat("HH:mm:ss");
	public final static String dateStr = "yyyy-MM-dd";

	/** 序列化对象 

     * ＠throws IOException */ 

    public static byte[] serializeObject(Object object) throws IOException{ 

       ByteArrayOutputStream saos=new ByteArrayOutputStream(); 

       ObjectOutputStream oos=new ObjectOutputStream(saos); 

       oos.writeObject(object); 

       oos.flush(); 

       return saos.toByteArray() ; 
 
    }
    
    /** 反序列化对象 

     * ＠throws IOException 

     * ＠throws ClassNotFoundException */ 

    public static Object deserializeObject(byte[]buf) throws IOException, ClassNotFoundException{ 

       Object object=null; 

       ByteArrayInputStream sais=new ByteArrayInputStream(buf); 

       ObjectInputStream ois = new ObjectInputStream(sais); 

       object= ois.readObject(); 

       return object; 

    }

	/**
	 * 获取本机IP地址
	 * 
	 * @return
	 */
	public static String getIPAddress() {
		String ip = "UNKNOW";
		Enumeration<NetworkInterface> niList = null;
		try {
			niList = NetworkInterface.getNetworkInterfaces();
		} catch (SocketException e) {
			log.error("获取本机IP地址时发生异常", e);
			return ip;
		}
		boolean isFind = false;
		while (niList.hasMoreElements()) {
			if (isFind) {
				break;
			}
			NetworkInterface nic = niList.nextElement();
			Enumeration<InetAddress> addrs = nic.getInetAddresses();
			while (addrs.hasMoreElements()) {
				InetAddress ia = addrs.nextElement();
				if (!ia.isLoopbackAddress() && ia.isSiteLocalAddress() && ia.getHostAddress().indexOf(":") == -1) {
					ip = ia.getHostAddress();
					isFind = true;
					break;
				}
			}
		}
		return ip;
	}

	/**
	 * 获取当前日期
	 * @return
	 */

	public static String getCurrentTimeStr() {

		String startTime = "2011-12-01 00:00:00";

		try {
			Calendar calendar = Calendar.getInstance();

			Date startDate = calendar.getTime();

			startTime = simpleFormat.format(startDate);
		} catch (Exception e) {
			log.error("日期转换出现异常:", e);
		}
		return startTime;
	}

	/**
	 * 获取当前时间，去除秒、毫秒并去整数时间
	 * 
	 * @return
	 */
	public static long getCurrentTime() {
		Calendar calendar1 = Calendar.getInstance();
		// 将秒设置为0
		calendar1.set(Calendar.SECOND, 0);
		calendar1.set(Calendar.MILLISECOND, 0);

		int minuteSection = calendar1.get(Calendar.MINUTE);
		if (minuteSection % 2 > 0) {
			calendar1.set(Calendar.MINUTE, minuteSection + 1);
		}

		long ctime = calendar1.getTimeInMillis();
		return ctime;
	}

	/**
	 * 判断是否为数字
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		return pattern.matcher(str).matches();
	}

	/**
	 * 将字符串转化为数字
	 * 
	 * @param str
	 * @return
	 */
	public static int parseStr2Num(String str) {
		int num = 0;
		if (str != null) {
			try {
				num = Integer.parseInt(str.trim());
			} catch (Exception e) {
				log.error("异常：" + e);
			}
		}
		return num;
	}

	/**
	 * 将字符串转化为double
	 * 
	 * @param str
	 * @return
	 */
	public static double parseStr2Double(String str) {
		double num = 0F;
		if (str != null) {
			try {
				num = Double.parseDouble(str.trim());
			} catch (Exception e) {
				log.error("异常：" + e);
			}
		}
		return num;
	}

	/**
	 * 字符串转化
	 * 
	 * @param str
	 * @return
	 */
	public static String StringUtil(String str) {
		if (str == null || "null".equals(str) || "".equals(str.trim())) {
			return null;
		} else {
			return str.trim();
		}
	}

	/**
	 * 获取起始日期
	 * 
	 * @param startTime
	 * @return
	 */

	public static String getStartTime(String startTime) {
		SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar calendar = Calendar.getInstance();

		// 如果查询日期为空，则将当前日期减去五天作为起始日期
		calendar.add(Calendar.DAY_OF_MONTH, -5);
		calendar.set(Calendar.HOUR_OF_DAY, 00);
		calendar.set(Calendar.MINUTE, 00);
		calendar.set(Calendar.SECOND, 00);
		Date startDate = calendar.getTime();

		if (startTime == null || "null".equals(startTime)) {
			startTime = simpleFormat.format(startDate);
		}
		return startTime;
	}

	/**
	 * 获取结束日期
	 * 
	 * @param endTime
	 * @return
	 */
	public static String getEndTime(String endTime) {
		SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar calendar = Calendar.getInstance();
		// 当前时间作为结束日期
		calendar = Calendar.getInstance();
		if (endTime == null || "null".equals(endTime) || "".equals(endTime)) {
			endTime = simpleFormat.format(calendar.getTime());
		}
		return endTime;
	}

	/**
	 * 将list元素 转成 逗号隔开的字符串 <功能详细描述>
	 * 
	 * @param list
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static String listParseString(String[] list) {
		StringBuilder bd = new StringBuilder();

		for (int i = 0, size = list.length; i < size; i++) {
			if (i == size - 1) {
				bd.append(list[i]);
			} else {
				bd.append(list[i]).append(",");
			}
		}
		return bd.toString();
	}

	/**
	 * 将字符串(日期)转化为date ** <功能详细描述>
	 * 
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static Date getStrParseDate(String dateStr) {

		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date d = null;
		try {
			d = df.parse(dateStr);// 2011-09-15 09:53:46
		} catch (ParseException e) {
			// e.printStackTrace();
			log.error("ParseException:", e);
		}
		return d;
	}

	/**
	 * date类型转String <功能详细描述>
	 *
	 * @param date
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static String dateParseStrByFormatStr(Date date) {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
	}

	/**
	 * date类型转String <功能详细描述>
	 * 
	 * @param date
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static String dateParseStrByFormatStrSt(Date date, String str) {
		return new SimpleDateFormat(str).format(date);
	}

	/**
	 * 获取字符串的长度，如果有中文，则每个中文字符计为2位
	 * 
	 * @param value
	 *            指定的字符串
	 * @return 字符串的长度
	 */
	public static final int length(String value) {
		int valueLength = 0;
		String chinese = "[\u0391-\uFFE5]";
		/* 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1 */
		for (int i = 0; i < value.length(); i++) {
			/* 获取一个字符 */
			String temp = value.substring(i, i + 1);
			/* 判断是否为中文字符 */
			if (temp.matches(chinese)) {
				/* 中文字符长度为2 */
				valueLength += 2;
			} else {
				/* 其他字符长度为1 */
				valueLength += 1;
			}
		}
		return valueLength;
	}

	/**
	 * 截取中英文混合字符串
	 * 
	 * @param text
	 *            目标字符串
	 * @param length
	 *            截取长度
	 * @param encode
	 *            采用的编码方式
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static final String substring(String text, int length, String encode) throws UnsupportedEncodingException {
		if (text == null) {
			return null;
		}
		StringBuilder sb = new StringBuilder();
		int currentLength = 0;
		for (char c : text.toCharArray()) {
			currentLength += String.valueOf(c).getBytes(encode).length;
			if (currentLength <= length) {
				sb.append(c);
			} else {
				break;
			}
		}
		return sb.toString();
	}



	// 更改日期格式
	public static String trans_opendt(String date) {
		SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy hh:mma", Locale.US);

		Date d = null;
		try {
			d = sdf.parse(date);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		sdf = new SimpleDateFormat("yyyy/MM/dd ");
		// "yyyy-MM-dd HH:mm:ss"
		// sdf=new SimpleDateFormat("HH:mm:ss");

		return sdf.format(d);
	}

	/**
	 * 将十六位进制的BYTE[] 转化为String
	 * 
	 * @param src
	 * @return
	 */
	public static String bytesToHexString(byte[] src, int srcLen) {
		StringBuilder stringBuilder = new StringBuilder("");
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < srcLen; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}

	/**
	 * Convert hex string to byte[]
	 * 
	 * @param hexString
	 *            the hex string
	 * @return byte[]
	 */
	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	/**
	 * 获取UUID
	 * 
	 * @return
	 */
	public static String getUUID() {
		String uuid = UUID.randomUUID().toString();
		uuid = uuid.replaceAll("-", "");
		return uuid;

	}

	/**
	 * 获取20位UUID
	 * 
	 * @return
	 */
	public static String getSubUUID() {
		String uuid = UUID.randomUUID().toString();
		uuid = uuid.replaceAll("-", "");
		uuid = uuid.substring(13, 32);
		return uuid;
	}

	/**
	 * 去除BCD码的末尾 "00"的无效字符
	 * 
	 * @param str
	 * @return
	 */
	public static String removeDoubleZero(String str) {

		if (StringUtil(str) != null && str.length() > 2 && "00".equals(str.substring(str.length() - 2, str.length()))) {
			str = str.substring(0, str.length() - 2);
			str = removeDoubleZero(str);
		} else {
			return str;
		}
		return str;
	}

	// 数字左补零
	public static final String rightPaddingWithZero(long data, int len) {
		String format = "%1$0" + len + "d";
		return String.format(format, data);
	}



	/**
	 * // 进行加法运算
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static double add(double d1, double d2){  
		
	         BigDecimal b1 = new BigDecimal(d1);
	         BigDecimal b2 = new BigDecimal(d2);
	        return b1.add(b2).doubleValue();
	 }
	/**
	 * // 进行减法运算
	 * @param d1
	 * @param d2
	 * @return
	 */
	    public static double sub(double d1, double d2){
	    	
	       BigDecimal b1 = new BigDecimal(d1);
	       BigDecimal b2 = new BigDecimal(d2);
	       return b1.subtract(b2).doubleValue();
	 }
	
	/**
	 * 进行乘法运算
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static double mul(double d1, double d2) { 
		
		BigDecimal b1 = new BigDecimal(d1);
		BigDecimal b2 = new BigDecimal(d2);
		return b1.multiply(b2).doubleValue();
	}
	/**
	 *  进行除法运算
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static double div(double d1, double d2, int len) {
		
		if(d2==0){
			return 0;
		}
		BigDecimal b1 = new BigDecimal(d1);
		BigDecimal b2 = new BigDecimal(d2);
		return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).setScale(4,BigDecimal.ROUND_HALF_UP).doubleValue();
	}
	
	




	/**
	 * 追加文件：使用FileWriter
	 * 
	 * @param fileName
	 * @param content
	 */
	public static void writeIntoFile(String fileName, String content) {
		try {
			// 打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件
			FileWriter writer = new FileWriter(fileName, true);
			writer.write(content);
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	

	/*** 
     * MD5加密 生成32位md5码
     * @return 返回32位md5码
     */
    public static String md5Encode(String inStr) throws Exception {
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (Exception e) { e.printStackTrace();
            return "";
        }

        byte[] byteArray = inStr.getBytes("UTF-8");
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuilder hexValue = new StringBuilder();
		for (byte md5Byte : md5Bytes) {
			int val = ((int) md5Byte) & 0xff;
			if (val < 16) {
				hexValue.append("0");
			}
			hexValue.append(Integer.toHexString(val));
		}
        return hexValue.toString();
	
	
    }


	/**
	 * 获取菜单孩子节点
	 * @param allMenu
	 * @param menu
	 * @return
	 */
	public static List<MenuEntity> getChildren(List<MenuEntity> allMenu, MenuEntity menu){
		return allMenu.stream().filter(entity -> entity.getPid()!=null&&entity.getPid().intValue() == menu.getId().intValue()).collect(Collectors.toList());
	}

	/**
	 * 构建菜单树
	 * @param allMenu
	 * @param menu
	 */
	public static void buildTree(List<MenuEntity> allMenu,MenuEntity menu){
		List<MenuEntity> children = getChildren(allMenu,menu);
		if(children!=null&&!children.isEmpty()){
			for(MenuEntity entity:children){
                buildTree(allMenu,entity);
			}
			menu.setChildren(children);
		}
	}

}
 
